package com.jiawa.train.business.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSON;
import com.jiawa.train.business.domain.ConfirmOrder;
import com.jiawa.train.business.dto.ConfirmOrderMQDto;
import com.jiawa.train.business.enums.ConfirmOrderStatusEnum;
import com.jiawa.train.business.enums.RocketMQTopicEnum;
import com.jiawa.train.business.enums.SkTokenEnum;
import com.jiawa.train.business.mapper.ConfirmOrderMapper;
import com.jiawa.train.business.req.ConfirmOrderDoReq;
import com.jiawa.train.business.req.ConfirmOrderTicketReq;
import com.jiawa.train.common.exception.BusinessException;
import com.jiawa.train.common.exception.BusinessExceptionEnum;
import com.jiawa.train.common.util.MemberContext;
import com.jiawa.train.common.util.SnowUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
public class BeforeConfirmOrderService {
   @Resource
   private ConfirmOrderMapper confirmOrderMapper;

   @Resource
   private SkTokenService skTokenService;

//   @Resource
//   private RocketMQTemplate rocketMQTemplate;

   @Resource
   private ConfirmOrderService confirmOrderService;

   //在执行核心业务之前，先进行获取令牌资源，进行锁资源进行订单的初始化
   public Long beforeConfirmOrder(ConfirmOrderDoReq req)  {
      //1.进行令牌校验
      validateSkToken(req);
      //2.进行订单的初始化
      ConfirmOrder confirmOrder = createInitOrder(req);
      //3.将memberId进行存储在ConfirmOrderMQDto中进行传递
      ConfirmOrderMQDto confirmOrderMQDto = new ConfirmOrderMQDto();
      confirmOrderMQDto.setLogId(MDC.get("LOG_ID"));
      confirmOrderMQDto.setDate(req.getDate());
      confirmOrderMQDto.setTrainCode(req.getTrainCode());
      confirmOrderMQDto.setMemberId(MemberContext.getMember());
      //3.将消息进行发送到rocketMq中
      JSON confirmOrderMQDtoJson = JSON.parseObject(JSON.toJSONString(confirmOrderMQDto));
      log.info("发送消息:{}", confirmOrderMQDtoJson);
      //使用枚举类型进行统一
//      rocketMQTemplate.convertAndSend(RocketMQTopicEnum.CONFIRM_ORDER.getCode(), confirmOrderMQDtoJson);
      confirmOrderService.doConfirmOrder(confirmOrderMQDto);
      return confirmOrder.getId();
   }
   //(1)进行获取令牌资源
   private void validateSkToken(ConfirmOrderDoReq req) {
      //先获取到用户购买的座位类型
      List<ConfirmOrderTicketReq> Membertickets = req.getTickets();
      //先进行令牌的校验，令牌校验通过之后在进行后续的操作，否则抛出异常
      SkTokenEnum flag  = skTokenService.validSkToken(req.getDate(), req.getTrainCode(), Membertickets , MemberContext.getMember());
      switch (flag){
         case ERROR_NOT_FOUND:
            throw new BusinessException(BusinessExceptionEnum.CONFIRM_ORDER_SK_TOKEN_ERROR);
         case ERROR_YDZ_NOT_ENOUGH:
            throw new BusinessException(BusinessExceptionEnum.CONFIRM_ORDER_SK_TOKEN_YDZ_ERROR);
         case ERROR_EDZ_NOT_ENOUGH:
            throw new BusinessException(BusinessExceptionEnum.CONFIRM_ORDER_SK_TOKEN_EDZ_ERROR);
         case SUCCESS:
            log.info("恭喜，令牌校验成功！");
            break;
      }
   }
   //(2)进行订单的初始化
   private ConfirmOrder createInitOrder(ConfirmOrderDoReq req) {
      DateTime now = DateTime.now();
      ConfirmOrder confirmOrder = BeanUtil.copyProperties(req, ConfirmOrder.class);
      confirmOrder.setId(SnowUtil.getSnowflakeNextId());
      confirmOrder.setUpdateTime(now);
      confirmOrder.setCreateTime(now);
      //在用户登录过后，网关使用请求头传递用户的memberId,然后使用请求拦截器进行拦截获取用户的memberId,将其存储在线程中
      log.info("用户的memberId:{}", MemberContext.getMember());
      confirmOrder.setMemberId(MemberContext.getMember());
      confirmOrder.setStatus(ConfirmOrderStatusEnum.INIT.getCode());
      confirmOrder.setTickets(JSON.toJSONString(req.getTickets()));
      confirmOrderMapper.insert(confirmOrder);
      return confirmOrder;
   }
}
